跳至主要内容

關於 Swiper 設計方式和循環模式

· 閱讀時間約 4 分鐘
Imagine Chiu
Front End Engineer @ Bearests

研究輪播機制系列

swiper banner

因為前陣子開發文字動態效果,在Clone項目上需要重置時, 會導致動畫無法連貫,所以就想說來看看目前的 Swiper 有沒有這個問題。

於事,發現了他已經不使用 Clone 的方式了。

一般情況

Normal State

可以看到,一般情況下,該方法類似於實現輪播的一般方法。

遇到需要 Clone 的情況

Need Loop State

我們從 aria-label 中的信息可以看出,active item 被移動到第一個位置,然後序列繼續

對於每一個動作,我們只需要激活 transition-duration 動畫

運動完成後,動畫停用,運動控制應鎖定,直到運動完成

但實際上是

// active 5 (is last)
1 / 5 (-1496 * 0)
2 / 5 (-1496 * 1)
3 / 5 (-1496 * 2)
4 / 5 (-1496 * 3)
5 / 5 (-1496 * 4)

// click next, active 1
// then duration 0ms, transform: -4488px,
// then duration: 900ms, transform: -5984px,
// move
2 / 5 (0)
3 / 5 (-1496px)
4 / 5 (-2992px)
5 / 5 (-4488px)
1 / 5 (-5984px)
// then duration 0ms


// click next, active 2
// then duration 0ms, transform: -4488px,
// then duration: 900ms, transform: -5984px,
3 / 5 (0)
4 / 5 (-1496px)
5 / 5 (-2992px)
1 / 5 (-4488px)
2 / 5 (-5984px)
// then duration 0ms

因為速度太快看不出破綻,下面是大概的重現方式

containerEl.style.transform = `translate3d(${-1904}px, 0px, 0px)`;
containerEl.style.transitionDuration = '0ms';
setTimeout(() => {
containerEl.style.transform = `translate3d(${-3808}px, 0px, 0px)`;
containerEl.style.transitionDuration = `${this._configurator.setting.moveTime}ms`;
}, 0);

於是補上將下一個目標序列移動到最後一個,然後跳轉到上一個位置,再移動到最後一個 排序變了,就變成了判斷是最後還是第一個,按順序判斷


可以解決什麼問題

我本來以為要循環,必須複製然後立即替換和重置,通過這樣做,我們可以避免與額外複製相關的問題以及輪播項目不同的情況

每次都需要創建新輪播項目(依照需要復制的數量),通常是輪播項目中有動態效果時比較容易受到影響

會產生什麼問題

Loop mode, total item 5, slidePreView 3

  • 因為改變數組順序需要重新渲染 (值得思考的是,如果真的改變了數組的順序,可以考慮是否使用css order來達到同樣的效果)

  • 當數量無法整除移動群數時,當數量無法整除移動群數時,順序切換補間會出現破綻

  • 手動滑動的時候,或者數量不夠的時候,很難判斷切換順序是依照 開頭還是結尾

  • 第一頁指定移動到最後一頁的時候,很難瞬間在 動畫移動中切換順序(除非使用 requestAnimationFrame)

Tip

到目前為止,使用克隆可能仍然是利大於弊。

Ref

測試不使用Clone的分支